﻿using Minecraft.Config;
using Minecraft.Config.Csv.CsvCls;
using Minecraft.Model;
using Minecraft.Model.Backpack;
using Minecraft.Model.Dropinfo;
using Minecraft.Model.ReqResp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Minecraft.ServerHall
{
	public static class BackpackExt
	{
		/// <summary>
		/// 判断背包是否已经满了
		/// </summary>
		/// <param name="session"></param>
		/// <returns></returns>
		public static void IsBackpackFull(this MinecraftSession session, out BaseResp baseResp, out bool isFull, out List<BackpackGoodsItemInfo> canPlacedBpCellInfoList)
		{
			canPlacedBpCellInfoList = new List<BackpackGoodsItemInfo>();
			isFull = false;
			var bpGoodsItemInfoList = session.GetBackpackGoodsItemInfoList(EnumGoodsBelongsToType.Backpack, "", out baseResp);
			if (baseResp.RespLevel != RespLevelEnum.Success)
			{
				return;
			}
			//得到可以放置的格子信息
			canPlacedBpCellInfoList = bpGoodsItemInfoList.Where(m =>
			{
				return m.GoodsNum <= 0 || m.GoodsNum < session.GetMaxCellNumConvert(m.GoodsItemId);
			}).ToList();
			if (canPlacedBpCellInfoList == null || !canPlacedBpCellInfoList.Any())
			{
				isFull = true;
				return;
			}
			isFull = false;
		}
		/// <summary>
		/// 将奖励物品插入背包（物品来自于掉落表）
		/// </summary>
		/// <param name="session"></param>
		/// <param name="dropId"></param>
		/// <param name="dropinfoDropResourceInfoList">掉落资源信息列表</param>
		/// <param name="posGoodsinfoList">背包插入物品后受影响的物品位置信息</param>
		/// <param name="dropAttributeList">掉落的属性列表</param>
		/// <param name="attributeList">属性列表（玩家的属性变化）</param>
		/// <returns></returns>
		public static BaseResp InsertGoodsToBackpackFromDropId(this MinecraftSession session, string dropId,
			out List<DropinfoDropResourceInfo> dropinfoDropResourceInfoList,
			out List<BackpackCellInfo> posGoodsinfoList,
			out List<KeyValueEnumAttributeInt> dropAttributeList,
			out List<KeyValueEnumAttributeInt> attributeList)
		{
			dropinfoDropResourceInfoList = new List<DropinfoDropResourceInfo>();
			posGoodsinfoList = new List<BackpackCellInfo>();
			dropAttributeList = new List<KeyValueEnumAttributeInt>();
			attributeList = new List<KeyValueEnumAttributeInt>();

			Mod_Drop mod_Drop = CsvConfig.GetMod_DropInfoById(dropId);
			if (mod_Drop == null)
			{
				return new BaseResp { RespLevel = RespLevelEnum.Error, Msg = $"错误1：（原因：掉落配置表中id为【{dropId}】的掉落信息为空）" };
			}
			switch (mod_Drop.enumDropType_Convert)
			{
				case EnumDropType.Unknown:
					{
						return new BaseResp { RespLevel = RespLevelEnum.Error, Msg = $"错误1：（原因：mod_Drop.enumDropType_Convert：【{mod_Drop.enumDropType_Convert}】）" };
					}
					break;
				case EnumDropType.Stochastic:
					{
						dropinfoDropResourceInfoList = session.GetDropinfoDropRandomResourceInfoList(mod_Drop.Id);
					}
					break;
				case EnumDropType.Certainly:
					{
						dropinfoDropResourceInfoList = mod_Drop.GetModDropAchieveInfoList().Select(m => new DropinfoDropResourceInfo()
						{
							GoodsItemId = m.GoodsItemId,
							Num = m.Num
						}).ToList();
					}
					break;
				case EnumDropType.StochasticAndCertainly:
					{
						dropinfoDropResourceInfoList.AddRange(session.GetDropinfoDropRandomResourceInfoList(mod_Drop.Id));
						dropinfoDropResourceInfoList.AddRange(mod_Drop.GetModDropAchieveInfoList().Select(m => new DropinfoDropResourceInfo()
						{
							GoodsItemId = m.GoodsItemId,
							Num = m.Num
						}).ToList());
					}
					break;
				default:
					{
						return new BaseResp { RespLevel = RespLevelEnum.Error, Msg = $"错误1：（原因：mod_Drop.enumDropType_Convert：【{mod_Drop.enumDropType_Convert}】）" };
					}
					break;
			}
			var exceptExpResourceList = dropinfoDropResourceInfoList.Where(m => m.GoodsItemId != MinecraftConfig.ExperienceItemId).ToList();
			//判断背包是否已经满了，如果已经满了，则不允许采集
			session.IsBackpackFull(out BaseResp baseResp, out bool isFull, out List<BackpackGoodsItemInfo> canPlacedBpCellInfoList);
			if (baseResp.RespLevel != RespLevelEnum.Success)
			{
				return baseResp;
			}
			if (isFull) //背包已经满了
			{
				return new BaseResp { RespLevel = RespLevelEnum.Error, Msg = $"错误1：（原因：背包已经满了）" };
			}

			//要保证所有的掉落物品都能装入背包才可以
			foreach (var exceptExpResource in exceptExpResourceList)
			{
				var canPlacedInfo = canPlacedBpCellInfoList.FirstOrDefault(m => m.GoodsNum <= 0 ||
				m.GoodsItemId == exceptExpResource.GoodsItemId && m.GoodsNum < session.GetMaxCellNumConvert(exceptExpResource.GoodsItemId));
				if (canPlacedInfo != null)
				{
					canPlacedInfo.GoodsItemId = exceptExpResource.GoodsItemId;
					canPlacedInfo.GoodsNum += exceptExpResource.Num;
				}
				else
				{
					return new BaseResp { RespLevel = RespLevelEnum.Error, Msg = $"错误1：（原因：背包已经满了，不能再装东西了）" };
				}
			}

			baseResp = session.DropAddExp(dropinfoDropResourceInfoList, dropAttributeList, attributeList);
			if (baseResp.RespLevel != RespLevelEnum.Success)
			{
				return baseResp;
			}

			//添加操作影响的positionOptList
			List<BackpackGoodsPositionOpt> positionOptList = new List<BackpackGoodsPositionOpt>();
			//将掉落的物品直接放入背包
			foreach (var dropinfoDropResourceInfo in dropinfoDropResourceInfoList)
			{
				var guid = "";
				//从配置中读取指定物品存放数量上限
				var goodsItemMaxNum = session.GetMaxCellNumConvert(dropinfoDropResourceInfo.GoodsItemId);
				//加载背包物品goodsItem信息
				List<BackpackGoodsItemInfo> goodsItemInfoList = session.GetBackpackGoodsItemInfoList(EnumGoodsBelongsToType.Backpack, guid, out baseResp);
				if (baseResp.RespLevel != RespLevelEnum.Success)
				{
					return baseResp;
				}

				//找到能够满足存放物品条件的位置信息
				Func<BackpackGoodsItemInfo, bool> predicate = m =>
					(m.GoodsNum <= 0 || m.GoodsItemId == dropinfoDropResourceInfo.GoodsItemId && m.GoodsNum < goodsItemMaxNum) && m.guid == guid;

				var goodsItemInfo2 = goodsItemInfoList.FirstOrDefault(predicate);
				if (goodsItemInfo2 == null)
				{
					return new BaseResp { RespLevel = RespLevelEnum.Error, Msg = "格子已经满了，或者guid对应的信息不存在" };
				}
				goodsItemInfo2.GoodsItemId = dropinfoDropResourceInfo.GoodsItemId;

				//获取可以插入的num数
				var canInsertNum = Math.Min(dropinfoDropResourceInfo.Num, session.GetMaxCellNumConvert(goodsItemInfo2.GoodsItemId) - goodsItemInfo2.GoodsNum);
				goodsItemInfo2.GoodsNum += canInsertNum;

				var goodsInfo = session.minecraftSessionInfo.goodsList.FirstOrDefault(m =>
				m.enumGoodsBelongsToType_Convert == goodsItemInfo2.enumGoodsBelongsToType
				&& m.GoodsPosition == goodsItemInfo2.GoodsPosition
				&& m.guid == goodsItemInfo2.guid
				);
				//更新内存
				if (goodsInfo == null)
				{
					goodsInfo = new GoodsModel
					{
						BelongsTo = (int)goodsItemInfo2.enumGoodsBelongsToType,
						GoodsId = StringHelper.GetGuidStr(),
						GoodsItemId = goodsItemInfo2.GoodsItemId,
						GoodsPosition = goodsItemInfo2.GoodsPosition,
						guid = goodsItemInfo2.guid,
						Num = goodsItemInfo2.GoodsNum,
						PlayerId = session.minecraftSessionInfo.player.PlayerId,
						WastageValue = 100,
					};
					session.minecraftSessionInfo.goodsList.Add(goodsInfo);
				}
				else
				{
					goodsInfo.Num = goodsItemInfo2.GoodsNum;
				}

				if (!positionOptList.Any(m => m.enumGoodsBelongsToType == goodsItemInfo2.enumGoodsBelongsToType && m.GoodsPosition == goodsItemInfo2.GoodsPosition && m.guid == goodsItemInfo2.guid))
				{
					positionOptList.Add(new BackpackGoodsPositionOpt
					{
						enumGoodsBelongsToType = goodsItemInfo2.enumGoodsBelongsToType,
						GoodsPosition = goodsItemInfo2.GoodsPosition,
						guid = goodsItemInfo2.guid
					});
				}
			}
			//找到受影响的物品位置信息
			Func<GoodsModel, bool> predicateBeAffected = m =>
				(positionOptList.Any(n => n.enumGoodsBelongsToType == m.enumGoodsBelongsToType_Convert
				&& n.GoodsPosition == m.GoodsPosition && n.guid == m.guid));
			posGoodsinfoList = session.minecraftSessionInfo.goodsList.Where(predicateBeAffected).GetBackpackGoodsCellInfo();

			return new BaseResp();
		}
	}
}
